#pragma once
#ifndef _KH_ENGINE_COMMON_H
#define _KH_ENGINE_COMMON_H

#if defined(_DEBUG) && defined(KH_ENGINE_DEBUG_ALLOC)
# define _CRTDBG_MAP_ALLOC
# include <stdlib.h>
# include <crtdbg.h>
#endif

// Kharlia Core
#include <Kharlia/Core/Common.h>
#include <Kharlia/Core/Logger.h>
#include <Kharlia/Core/ObjectBase.h>

// Undef these to avoid annoying CEGUI warnings
#ifdef min
# undef min
#endif

#ifdef max
# undef max
#endif

// RakNet
#include <RakPeerInterface.h>
#include <RakNetTypes.h>
#include <MessageIdentifiers.h>
#include <BitStream.h>
#include <StringCompressor.h>
#include <RakNetTime.h>
#include <GetTime.h>
#include <ReplicaManager3.h>
#include <NetworkIDManager.h>

#undef main // Incompatible with Stackless

#ifdef KH_ENGINE_SOURCE
#  define KH_ENGINE_DECLSPEC __declspec(dllexport)
#else
#  define KH_ENGINE_DECLSPEC __declspec(dllimport)
#endif

/// Marks a function that calls a method of its name in Python
#define kh_pycall
/// Marks a function that must adhere to Python's MRO when calling
/// an base class function. Use GetSuper() to make the call.
#define kh_pymro

#include <Kharlia/Engine/Exceptions.h>

namespace CEGUI {}

namespace kharlia {
    namespace ui = ::CEGUI;
    namespace rn = ::RakNet;

    namespace core { namespace util {}}

    namespace engine {
        using namespace core::util; // Utility functions
        using namespace core::exc; // Exceptions

        // Reference to kharlia.__engine module
        extern KH_ENGINE_DECLSPEC object GetInnerModuleAttr(str name);
        // Reference to kharlia._engine module
        extern KH_ENGINE_DECLSPEC object GetModuleAttr(str name);
        extern KH_ENGINE_DECLSPEC void SetModuleAttr(str name, object value);
    }
}

#endif
